package gui;

import graph.ImageUtils;
import graph.MostrarPuntajes;
import graph.NuevoJuego;

import java.awt.Color;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.HashMap;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;

import back.Agujero;
import back.Archivos;
import back.Caja;
import back.Camino;
import back.Celda;
import back.Coordenada;
import back.Destino;
import back.Juego;
import back.Jugador;
import back.Movible;
import back.NoMovible;
import back.Pared;
import back.Tablero;
import back.Vacio;
import back.VacioM;


public class ImprimeTablero extends JFrame{
	
	private static final long serialVersionUID = 1L;

	private static final int CELL_SIZE = 30;
	
	
	private BoardPanel bp;
	private HashMap<Class, Image> imagenes; 
	private Image img;
	
	public ImprimeTablero(final Juego juego) {
		Tablero tablero= juego.getTablero();
		setSize(tablero.getCols() * (CELL_SIZE + 2), tablero.getFils() * (CELL_SIZE + 10));

		try {
			imagenes=new HashMap<Class,Image>();
			img=ImageUtils.loadImage("resources/box.png");
			imagenes.put(Caja.class, ImageUtils.loadImage("resources/box.png"));
			imagenes.put(Agujero.class, ImageUtils.loadImage("resources/hole.png"));
			imagenes.put(Pared.class, ImageUtils.loadImage("resources/wall.jpg"));
			imagenes.put(Camino.class,ImageUtils.loadImage("resources/path.png"));
			imagenes.put(Destino.class, ImageUtils.loadImage("resources/target.png"));
			imagenes.put(Jugador.class, ImageUtils.loadImage("resources/smile.png"));
		
		} catch (IOException e) {
			System.out.println("Error al cargar imagenes.");
		}
		
		bp = new BoardPanel(tablero.getFils(), tablero.getCols(), CELL_SIZE);
		bp.setBackground(Color.WHITE);
		add(bp);
		addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent e) {
                try {
					actualiza(e.getKeyCode(), true);
				} catch (FileNotFoundException e1) {
				} catch (IOException e1) {
				}
            }

//            public void keyReleased(KeyEvent e) {
//                actualiza(e.getKeyCode(), false);
//            }

            private void actualiza(int keyCode, boolean pressed) throws FileNotFoundException, IOException {
                switch (keyCode) {
                    case KeyEvent.VK_UP:
                        juego.hacerMov(2);
                        ImprimeTablero imp=new ImprimeTablero(juego);
						imp.imprime(juego);
						imp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
						imp.setVisible(true);
						setVisible(false);
                        break;

                    case KeyEvent.VK_DOWN:
                    	juego.hacerMov(0);
                        imp=new ImprimeTablero(juego);
						imp.imprime(juego);
						imp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
						imp.setVisible(true);
						setVisible(false);
                        break;

                    case KeyEvent.VK_LEFT:
                        juego.hacerMov(1);
                        imp=new ImprimeTablero(juego);
						imp.imprime(juego);
						imp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
						imp.setVisible(true);
						setVisible(false);
                        break;

                    case KeyEvent.VK_RIGHT:
                        juego.hacerMov(3);
                        imp=new ImprimeTablero(juego);
						imp.imprime(juego);
						imp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
						imp.setVisible(true);
						setVisible(false);
                        break;
                }
            }
        });
		
	}
	public void printImage(Image img, Coordenada coord){
		bp.setImage(coord.getX(), coord.getY(), img);
	}
	public Image dyeImage(Image img, Color color){
		return ImageUtils.dye(img, color);
	}

	public void imprime(final Juego juego){
		setTitle("SOKOBAN");
		JMenuBar menubar = new JMenuBar();
		  JMenu file = new JMenu("Juego");
	      file.setMnemonic(KeyEvent.VK_J);
	      JMenuItem newGame = new JMenuItem("Nuevo juego");
	      newGame.addActionListener(new ActionListener() {
		    	@Override
		    	public void actionPerformed(ActionEvent e) {
		    		new NuevoJuego();
		    	}
		      });
		      
	      JMenuItem loadGame = new JMenuItem("Cargar juego guardado");
	      loadGame.addActionListener(new ActionListener() {
		    	@Override
		    	public void actionPerformed(ActionEvent e) {
		    		JFileChooser selector=new JFileChooser("./guardados");
					selector.showOpenDialog(bp);
					File archivo=selector.getSelectedFile();
					if(archivo != null){
					try {
		    			File[] niveles;
						niveles = Archivos.cargarNiveles();
						Juego juego= new Juego(niveles);
						Archivos.cargaJuego(juego, archivo);
						ImprimeTablero imp=new ImprimeTablero(juego);
						imp.imprime(juego);
						imp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
						imp.setVisible(true);
						setVisible(false);
					} catch (FileNotFoundException e1) {
					} catch (IOException e1) {
					} }
		    	}
		      });
		      
	      JMenuItem saveGame = new JMenuItem("Guardar juego");
	      saveGame.addActionListener(new ActionListener() {
		    	@Override
		    	public void actionPerformed(ActionEvent e) {
		    		JFileChooser selector = new JFileChooser("./guardados");
					selector.setApproveButtonText("Save");
					selector.showSaveDialog(bp);
					File archivo = selector.getSelectedFile();
					
					try {
						if(archivo != null) {
							String[] paths = archivo.getPath().split("/");
							String path = paths[paths.length - 2];
							System.out.print(path);
							if(path.equals("archivos")) {
								throw new IllegalAccessException();
							}
							Archivos.guardarArchivo(juego, archivo);
						}
					} catch (Exception e1) {
						String mensaje = "<html>Problemas al guardar el archivo" +
						 				 "<br>Intente otro directorio</html>";
						//new MensajeFrame(mensaje);
					}
				}
			});

		      
	      saveGame.setMnemonic(KeyEvent.VK_G);
	      JMenuItem scores = new JMenuItem("Ver mejores puntajes");
	      scores.addActionListener(new ActionListener() {
		    	@Override
		    	public void actionPerformed(ActionEvent e) {
		    		new MostrarPuntajes();
		    	}
		      });
		      
	      
	      file.add(newGame);
	      file.add(loadGame);
	      file.add(saveGame);
	      file.add(scores);
	      JMenu level=new JMenu("Nivel");
	      file.setMnemonic(KeyEvent.VK_N);
	      
	      JMenuItem restartLevel = new JMenuItem("Reiniciar nivel");
	      restartLevel.addActionListener(new ActionListener() {
		    	@Override
		    	public void actionPerformed(ActionEvent e) {
		    		try {
						juego.reiniciarNivel();
                        ImprimeTablero imp=new ImprimeTablero(juego);
						imp.imprime(juego);
						imp.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
						imp.setVisible(true);
						setVisible(false);
					} catch (FileNotFoundException e1) {
					} catch (IOException e1) {
					}
						
		    	}
		      });
	      level.add(restartLevel);
	      menubar.add(file);
	      menubar.add(level);
	      setJMenuBar(menubar);
		
		
		for(int i=0;i<juego.getTablero().getFils();i++){
			for(int j=0;j<juego.getTablero().getCols();j++){
				Coordenada coord = new Coordenada(i, j);
				Celda celda = juego.getTablero().getCelda(coord);
				this.ImprimeNoMov(celda, coord);
				this.ImprimeMov(celda, coord);
			}
		}
	}
	
	public void ImprimeNoMov(Celda celda, Coordenada coord){
		int i=coord.getX(), j=coord.getY();
		NoMovible noMov=celda.getNoMovible();
		Class noMovC=noMov.getClass();
		if(noMovC==Vacio.class)
			return;
		if(noMov.getClass() == Camino.class){
				int direc= ((Camino)noMov).getDireccion();
				Image im=(Image)imagenes.get(noMovC);
				im= ImageUtils.rotateImage(im, direc);
				bp.setImage(i, j, im);
				return;
			}
		if(noMov.getClass() == Destino.class){
			Image im=(Image)imagenes.get(noMovC);
			Color color= ((Destino)noMov).getColor();
			im= ImageUtils.dye(im, color);
			bp.setImage(i, j, im);
			return;
		}
		
		bp.setImage(i, j, (Image)imagenes.get(noMovC));
			
		}
	
	public void ImprimeMov(Celda celda, Coordenada coord){
		int i=coord.getX(), j=coord.getY();
		Movible mov = celda.getMovible();
		Class clase = mov.getClass();
		if(clase==VacioM.class)
			return;
		if(mov.getClass() == Caja.class){
				Color color= ((Caja)mov).getColor();
				Image im=(Image)imagenes.get(clase);
				im= ImageUtils.dye(im, color);
				if(celda.brilla()){
					im=ImageUtils.increaseBrightness(im);
				}
				bp.setImage(i, j, im);
				return;
			}
		bp.setImage(i, j, (Image)imagenes.get(clase));
		}		
	
}
